package com.hospital.search.module.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import com.hospital.common.base.PageResult;
import com.hospital.common.dto.search.module.PostInsertDto;
import com.hospital.common.dto.search.module.PostQueryDto;
import com.hospital.common.dto.search.module.ReplyInsertDto;
import com.hospital.common.utils.LocalDateTimeUtils;
import com.hospital.common.vo.search.module.PostIndexVo;
import com.hospital.search.module.exception.SearchServiceException;
import com.hospital.search.module.exception.enums.SearchServiceExpCode;
import com.hospital.search.module.index.PostIndex;
import com.hospital.search.module.service.SearchService;
import com.hospital.search.module.utils.ElasticInsertUtils;
import com.hospital.search.module.utils.PostQueryBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;

@Service
public class SearchServiceImpl implements SearchService {
    @Autowired
    private PostQueryBuilder postQueryBuilder;
    @Autowired
    private ElasticsearchClient esClient;
    @Autowired
    private ElasticInsertUtils elasticInsertUtils;
    @Override
    public PageResult<PostIndexVo> search(PostQueryDto queryDto) {
        SearchResponse<PostIndex> response;
        try {
            response = esClient.search(
                    postQueryBuilder.build(queryDto),
                    PostIndex.class
            );
        } catch (IOException e) {
            throw new SearchServiceException(SearchServiceExpCode.SEARCH_SERVICE_ERROR);
        }
        long total = 0L;
        TotalHits hits = response.hits().total();
        if (!ObjectUtils.isEmpty(hits)) {
            total = hits.value();
        }
            return new PageResult<>(
                    total,
                    response.hits().hits().stream().map(Hit::source).map(this::convert).toList()
            );
    }
    private PostIndexVo convert(PostIndex postIndex){
        PostIndexVo postIndexVo = new PostIndexVo();
        BeanUtils.copyProperties(postIndex,postIndexVo);
        postIndexVo.setCreateTime(LocalDateTimeUtils.fromEpochMillis(postIndex.getCreateTime()));
        postIndexVo.setUpdateTime(LocalDateTimeUtils.fromEpochMillis(postIndex.getUpdateTime()));
        return postIndexVo;
    }

    @Override
    public void insertPost(PostInsertDto insertDto) {
        elasticInsertUtils.insertPost(insertDto);
    }

    @Override
    public void insertReply(ReplyInsertDto insertDto) {
        elasticInsertUtils.insertReply(insertDto);
    }
}
